﻿using Coolzon.Common;
using Coolzon.UI.Common.WebProxies;
using Coolzon.UI.Common.Widgets.Properties;
using Coolzon.UI.Core.Parts;
using Coolzon.UI.Core.Properties;
using Coolzon.Web.Models;
using CPPEI.Coolzon.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Coolzon.UI.Common.Widgets.DataTask
{
    /// <summary>
    /// 数据加载对应任务类
    /// </summary>
    public class DataLoadTask
    {
        private int _requestCount = 0;
        private int _responseCount = 0;

        /// <summary>
        /// 数据获取失败重试次数,失败3次后删除任务
        /// </summary>
        private int _retryCount = 0;

        /// <summary>
        /// 任务唯有标示
        /// </summary>
        public string Identity { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string UserIdentity { get; private set; }

        /// <summary>
        /// 数据源
        /// </summary>
        public DataSource DataSource { get; private set; }

        /// <summary>
        /// 数据集
        /// </summary>
        public DataSet DataSet { get; private set; }

        /// <summary>
        /// 参数
        /// </summary>
        public List<QueryParameter> Parameters { get; private set; }

        /// <summary>
        /// 组件列表
        /// </summary>
        public List<WeakReference> RelateParts { get; private set; }

        /// <summary>
        /// 任务是否完成
        /// </summary>
        public bool IsFinished { get; set; }

        /// <summary>
        /// 是否允许缓存，如果允许缓存那么数据将优先从缓存里获取，从服务器获取回来的数据也将被缓存，如果不允许缓存那么每次都会从服务器获取
        /// </summary>
        public bool IsCacheEnable { get; private set; }

        /// <summary>
        /// md5加密之后的identity
        /// </summary>
        public string MD5Identity { get; private set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dataPart"></param>
        /// <param name="userIdentity"></param>
        /// <param name="source"></param>
        /// <param name="set"></param>
        /// <param name="parameters"></param>
        public DataLoadTask(DataWidget dataPart, string userIdentity, DataSource source, DataSet set, List<QueryParameter> parameters)
        {
            if (source.IsStatic)
            {
                Identity = source.Name;
            }
            else
            {
                StringBuilder identityBuilder = new StringBuilder();
                identityBuilder.AppendFormat("user={0},source={1},set={2}", userIdentity, source.Name, set.Name);
                for (int index = 0; index < parameters.Count; index++)
                {
                    identityBuilder.AppendFormat(",{0}={1},", parameters[index].Name, parameters[index].ValueString);
                }
                Identity = identityBuilder.ToString();
            }

            this.UserIdentity = userIdentity;
            this.DataSource = source;
            this.DataSet = set;
            this.Parameters = parameters;

            RelateParts = new List<WeakReference>();
            RelateParts.Add(new WeakReference(dataPart));

            IsCacheEnable = true;

            MD5Identity = convertToMd5(Identity);
        }

        /// <summary>
        /// 带是否允许缓存参数的构造函数
        /// </summary>
        /// <param name="dataPart"></param>
        /// <param name="userIdentity"></param>
        /// <param name="source"></param>
        /// <param name="set"></param>
        /// <param name="parameters"></param>
        /// <param name="isCacheEnable"></param>
        public DataLoadTask(DataWidget dataPart, string userIdentity, DataSource source, DataSet set, List<QueryParameter> parameters, bool isCacheEnable)
            : this(dataPart, userIdentity, source, set, parameters)
        {
            IsCacheEnable = isCacheEnable;
        }

        /// <summary>
        /// 在已存在的任务中添加组件
        /// </summary>
        /// <param name="dataParts"></param>
        public void AddListDataPart(List<WeakReference> dataParts)
        {
            foreach (WeakReference dataPart in dataParts)
            {
                bool isExist = false;
                for (int index = 0; index < RelateParts.Count; index++)
                {
                    if (RelateParts[index].Target == dataPart.Target)
                    {
                        isExist = true;
                        break;
                    }
                }

                if (!isExist)
                {
                    RelateParts.Add(dataPart);
                }
            }
        }

        private string convertToMd5(string sourceStr)
        {
            MD5 newMd5 = new MD5CryptoServiceProvider();
            byte[] sourceBit = Encoding.Default.GetBytes(sourceStr);
            byte[] directBit = newMd5.ComputeHash(sourceBit);
            string directStr = BitConverter.ToString(directBit).Replace("-", "");
            return directStr;
        }

        /// <summary>
        /// 执行任务,首先从缓存中读取,缓存中不存在则异步从服务器读取
        /// </summary>
        public void Run()
        {
            DataResult result = null;

            if (DataSource.IsStatic)
            {
                //// 静态数据关闭缓存选项
                //IsCacheEnable = false;

                ////读取静态数据源
                //Designtime.IDataSourcePool dsPool = Designtime.ResPoolFactory.GetDataSourcePool();
                //if(dsPool == null)
                //{
                //    // 非设计运行环境
                //    result = UI.DataTask.StaticDataSourceManager.LoadDataFromSolution(DataSource.Name);
                //    if (result != null)
                //    {
                //        OnGetDataCallback(result, true, true);
                //    }
                //}
                //else
                //{
                //    // 设计环境
                //    string sdsContent = dsPool.GetStaticDataSource(DataSource.Name);
                //    result = UI.DataTask.StaticDataSourceManager.LoadDataFromContent(sdsContent);

                //    if (result != null)
                //    {
                //        OnGetDataCallback(result, true, true);
                //    }
                //}
            }
            else
            {
                if (this.IsCacheEnable)
                {
                    result = DataResultCache.LoadData(this);
                }

                if (result != null)
                {
                    OnGetDataCallback(result, true, true);
                }
                else
                {
                    result = WebProxy.Instance.GetDataResult(new LoadDataParam()
                    {
                        DataSource = this.DataSource.Name,
                        DataSet = this.DataSet.Name,
                        UserIdentity = this.UserIdentity,
                        Parameters = this.Parameters
                    });
                    if (result != null)
                    {
                        OnGetDataCallback(result, true, false);
                    }
                    else
                    {
                        OnGetDataCallback(result, false, false);
                    }
                }
            }
        }

        /// <summary>
        /// 异步从服务器获取数据后,传给对应的每个控件
        /// </summary>
        /// <param name="dataResult"></param>
        /// <param name="isSuccess"></param>
        /// <param name="isFromCacheFile"></param>
        public void OnGetDataCallback(DataResult dataResult, bool isSuccess = true, bool isFromCacheFile = false)
        {
            if (isSuccess && IsCacheEnable && !isFromCacheFile)
            {
                DataResultCache.SaveData(this, dataResult);
            }

            DataLoadTaskPool.Instance.RemoveTask(this);

            for (int index = 0; index < this.RelateParts.Count; index++)
            {
                if (this.RelateParts[index].Target != null)
                {
                    (this.RelateParts[index].Target as DataWidget).OnLoadDataCompleted(dataResult);
                }
            }
        }
    }
}
